home *** CD-ROM | disk | FTP | other *** search
/ FishMarket 1.0 / FishMarket v1.0.iso / fishies / 426-450 / disk_429 / v / v.a < prev    next >
Text File  |  1992-05-06  |  12KB  |  489 lines

  1. ;;; REMOVE DISK LOADING OF MORE
  2.  
  3. ; This is an entirely new version of V, the front end for Commodore's More.
  4. ; The old version ran More as a Workbench process, even when V was run from
  5. ; CLI, so that More would always open its own window.  This version always
  6. ; runs More as a CLI process, even when run from Workbench.  The reason for
  7. ; the change is that this way V can open More's window, and you can specify
  8. ; which window V will use with the environment variable MOREWINDOW (the
  9. ; default is "CON:0/0/640/200/More"), and also More's "E" command, which makes
  10. ; it pass the current file to the program in the environment variable EDITOR,
  11. ; only works when More is a CLI process.  (Note that it does NOT work when
  12. ; you run More (or V) with no argument, and it asks for a file and you tell
  13. ; it.  There is a bug in More that makes it think the name of the file it's
  14. ; showing is the same as the command in ENV:EDITOR.  Also the E command
  15. ; is not available when More is displaying from its standard input.)  This
  16. ; version of V runs More as part of its own process, and does not use the
  17. ; Execute() function.  This makes it more efficient at a slight cost in size.
  18. ; It is written in assembly to make it as small as possible, to minimize disk
  19. ; loading time when it is run from workbench, because the workbench can't use
  20. ; a resident copy of V (yes, it's pure).  Since V can use a resident copy of
  21. ; More, the workbench doesn't have to load that.  If More is not resident V
  22. ; will look for C:More or SYS:Utilities/More.  Maybe I should have an
  23. ; environment variable for that too?
  24.  
  25. ; V is by Paul Kienitz and is in the public domain.  I assembled it with the
  26. ; Aztec 5.0 assembler, but it should be compatible with other Amiga
  27. ; assemblers.  Requires no link libraries.  Use Aztec's -n one pass option.
  28. ; Last update 12/24/90.
  29.  
  30.  
  31.         include        "exec/types.i"
  32.         include        "exec/memory.i"
  33.         include        "exec/ports.i"
  34.         include        "workbench/startup.i"
  35.         include        "libraries/dosextens.i"
  36.  
  37.  
  38. fdef:        macro
  39. _LVO\1          equ        -\2
  40.         endm
  41.  
  42. ; exec funcs:
  43.         fdef        Forbid,132
  44.         fdef        AllocMem,198
  45.         fdef        FreeMem,210
  46.         fdef        FindTask,294
  47.         fdef        GetMsg,372
  48.         fdef        ReplyMsg,378
  49.         fdef        WaitPort,384
  50.         fdef        CloseLibrary,414
  51.         fdef        OpenLibrary,552
  52.  
  53. ; DOS funcs:
  54.         fdef        Open,30
  55.         fdef        Close,36
  56.         fdef        Read,42
  57.         fdef        Write,48
  58.         fdef        LoadSeg,150
  59.         fdef        UnLoadSeg,156
  60.         fdef        Delay,198
  61.  
  62. ; I found a mistake in Aztec's c.lib in version 5.0d:  all the dos.library
  63. ; offsets (_LVO...) are accidentally defined as positive numbers!  oooooops
  64. ; ... the mistake did not exist in 3.6a ... oh well, we make our own _LVO's.
  65.  
  66.  
  67. callib:        macro
  68.           jsr        _LVO\1(a6)
  69.         endm
  70.  
  71. callx:        macro
  72.           move.l    4,a6
  73.           callib    \1
  74.         endm
  75.  
  76. calld:        macro
  77.           move.l    dosbase,a6
  78.           callib    \1
  79.         endm
  80.  
  81.  
  82. ; a node on the resident program list:
  83.  
  84.         STRUCTURE    theResidents,0
  85.           BPTR        next
  86.           LONG        usecount
  87.           BPTR        seglist
  88.           UBYTE        namelength
  89.           BYTE        name        ; first char of var-length array
  90.  
  91.  
  92. ; local vars on the main program stack frame:
  93.  
  94.         STRUCTURE    mainargs,0
  95.           STRUCT    newa,300    ; char [300]
  96.           CPTR        wbm        ; workbench startup message
  97.           LONG        ret        ; our program return code
  98.           CPTR        cli        ; struct CommandLineInterface
  99.           LABEL        main_sizeof
  100.  
  101. winf        equr        d5        ; window filehandle
  102. mos        equr        d6        ; seglist of More if from disk
  103. alen        equr        d7        ; length of cmd argument line
  104. aptr        equr        a2        ; ptr to cmd argument line
  105. me        equr        a3        ; this process
  106. rezzy        equr        a4        ; struct theResidents
  107. ; rezzy is also temporarily used to point to our process's MsgPort
  108. dosbase        equr        a5        ; dos.library base
  109.  
  110. ; note: we follow a convention that you can trash regs d0-d4/a0/a1/a6.
  111.  
  112.  
  113. ; for debugging:
  114.         xdef        BEGIN,Start,dosname,morename,umorename,exit
  115.         xdef        ewinname,defaultwin,loaderrmsg,warnmsg
  116.         xdef        winerrmsg,makeCLI,doQuotes,runit,unLoad
  117.         xdef        GO_FER_IT,FindResiProg,CBsame,OpenWin,Mash
  118.         xdef        cmorename,emptyarg,MeasureAptr,getMore,notWB
  119.  
  120.  
  121. BEGIN:        bra        Start        ;;; ENTRY POINT
  122.  
  123.  
  124. dosname:    dc.b        "dos.library",0
  125. morename:    dc.b        "More",0
  126. umorename:    dc.b        "SYS:Utilities/More",0
  127. cmorename:    dc.b        "C:More",0
  128. ewinname:    dc.b        "ENV:MOREWINDOW",0
  129. defaultwin:    dc.b        "CON:0/0/640/200/More",0
  130. emptyarg:    dc.b        0
  131. loaderrmsg:    dc.b        "Can't find More in resident list, "
  132.         dc.b           "SYS:Utilities, or C:.",10,0
  133. loaderrlength    equ        56
  134. warnmsg:    dc.b        10,"*** Remember, DO NOT use the 'E' "
  135.         dc.b           "command this time!",10,0
  136. warnlength    equ        54
  137. winerrmsg:    dc.b        "Couldn't open window!",10,0
  138. winerrlength    equ        22
  139.  
  140.  
  141. ; ===================  here we go!
  142.  
  143. Start:        lea        -main_sizeof(sp),sp
  144.         move.l        d0,alen
  145.         move.l        a0,aptr
  146.         lea        dosname,a1
  147.         moveq        #0,d0
  148.         callx        OpenLibrary
  149.         move.l        d0,dosbase
  150.  
  151.         clr.l        ret(sp)
  152.         clr.l        wbm(sp)
  153.         sub.l        a1,a1
  154.         callx        FindTask
  155.         move.l        d0,me
  156.         add.l        #pr_MsgPort,d0
  157.         move.l        d0,rezzy
  158.  
  159.         tst.l        pr_CLI(me)
  160.         bne        notWB
  161.           move.l    rezzy,a0
  162.           callx        WaitPort
  163.           move.l    rezzy,a0
  164.           callib    GetMsg
  165.           move.l    d0,wbm(sp)
  166.  
  167. notWB:        bsr        OpenWin
  168.         move.l        d0,winf
  169.         lea        morename,a1
  170.         bsr        FindResiProg
  171.         move.l        d0,rezzy
  172.  
  173.         tst.l        pr_CLI(me)
  174.         beq        makeCLI
  175.           move.l    pr_CLI(me),d0
  176.           asl.l        #2,d0
  177.           move.l    d0,cli(sp)
  178.         bra        doQuotes
  179.  
  180. makeCLI:      tst.l        winf
  181.           beq        ret10
  182.           move.l    #cli_SIZEOF,d0
  183.           move.l    #MEMF_PUBLIC|MEMF_CLEAR,d1
  184.           callx        AllocMem
  185.           move.l    d0,cli(sp)
  186.           beq        ret10
  187.  
  188.             move.l    d0,a0
  189.             move.l    #1000,cli_DefaultStack(a0)
  190.             asr.l    #2,d0
  191.             move.l    d0,pr_CLI(me)
  192.             move.l    winf,pr_COS(me)
  193.  
  194.             lea        emptyarg,aptr
  195.             move.l    wbm(sp),a0
  196.             cmp.l    #1,sm_NumArgs(a0)
  197.             ble        emptyWBarg
  198.               move.l    sm_ArgList(a0),a0
  199.               addq    #wa_SIZEOF,a0
  200.               move.l    wa_Lock(a0),pr_CurrentDir(me)
  201.               move.l    wa_Name(a0),aptr
  202. emptyWBarg:        bsr        MeasureAptr
  203.           bra        doQuotes
  204. ret10:            move.l    #10,ret(sp)
  205.           bra        doQuotes
  206.  
  207. doQuotes:    lea        newa(sp),a0
  208.         bsr        Mash
  209.         lea        newa(sp),aptr
  210.         bsr        MeasureAptr
  211.  
  212.         tst.l        winf
  213.         beq        getMore
  214.         tst.l        alen
  215.         bne        getMore
  216.         move.l        pr_CIS(me),d0
  217.         move.l        cli(sp),a0
  218.         cmp.l        cli_StandardInput(a0),d0
  219.         bne        getMore
  220.           move.l    winf,d1
  221.           lea        warnmsg,a0
  222.           move.l    a0,d2
  223.           move.l    #warnlength,d3
  224.           calld        Write
  225.  
  226. getMore:    move.l        rezzy,d0        ; tst.l rezzy
  227.         bne        bumpCount
  228.           lea        umorename,a0        ; load More
  229.           move.l    a0,d1
  230.           calld        LoadSeg
  231.           move.l    d0,mos
  232.           bne        runit
  233.             lea        cmorename,a0
  234.             move.l    a0,d1
  235.             callib    LoadSeg
  236.             move.l    d0,mos
  237.             bne        runit
  238.               tst.l    pr_COS(me)        ; Can't load it!
  239.               beq    fail10
  240.             moveq    #loaderrlength,d3
  241.             lea    loaderrmsg,a0
  242.             move.l    a0,d2
  243.             move.l    pr_COS(me),d1
  244.             callib    Write
  245. fail10:              move.l    #10,ret(sp)
  246.               bra    runit
  247. bumpCount:      move.l    seglist(rezzy),mos
  248.           tst.l        usecount(rezzy)
  249.           ble        runit            ; >= 1 means addable
  250.             addq.l    #1,usecount(rezzy)    ; bump use count
  251.  
  252. runit:        tst.l        winf
  253.         beq        winErr
  254.         tst.l        ret(sp)
  255.         bne        winErr
  256.           move.l    cli(sp),a0
  257.           bsr        GO_FER_IT
  258.           move.l    d0,ret(sp)
  259.         bra        releaseIt
  260. winErr:          tst.l        pr_COS(me)
  261.           beq        nouh
  262.             move.l    pr_COS(me),d1
  263.             lea        winerrmsg,a0
  264.             move.l    a0,d2
  265.             move.l    #winerrlength,d3
  266.             calld    Write
  267. nouh:          move.l    #10,ret(sp)
  268.  
  269. releaseIt:    move.l        rezzy,d0        ; tst.l rezzy
  270.         beq        unLoad
  271.           cmp.l        #1,usecount(rezzy)
  272.           ble        flee
  273.             subq.l    #1,usecount(rezzy)
  274.         bra        flee
  275. unLoad:          move.l    mos,d1
  276.           calld        UnLoadSeg
  277.  
  278. flee:        tst.l        wbm(sp)
  279.         beq        exit
  280.           tst.l        cli(sp)
  281.           beq        noCLIf
  282.             move.l    cli(sp),a1
  283.             move.l    #cli_SIZEOF,d0
  284.             callx    FreeMem
  285. noCLIf:          callx        Forbid
  286.           move.l    wbm(sp),a1
  287.           callib    ReplyMsg
  288.  
  289. exit:        move.l        ret(sp),d0
  290.         lea        main_sizeof(sp),sp
  291.         rts
  292.  
  293.  
  294.  
  295. ; ====== this function actually runs More.  It returns More's return code.
  296. ; a0 contains pointer to our struct CommandLineInterface.
  297.  
  298. savregs        reg    a2-a6/d2-d7
  299.  
  300. GO_FER_IT:    move.l        pr_CIS(me),-(sp)
  301.         move.l        pr_COS(me),-(sp)
  302.         move.l        cli_StandardInput(a0),-(sp)
  303.         move.l        pr_ConsoleTask(me),-(sp)
  304.         move.l        a0,-(sp)
  305.         move.l        winf,pr_COS(me)
  306.         move.l        winf,d0
  307.         asl.l        #2,d0
  308.         move.l        d0,a1
  309.         move.l        fh_Type(a1),pr_ConsoleTask(me)
  310.         move.l        cli_StandardInput(a0),d0
  311.         cmp.l        pr_CIS(me),d0
  312.         bne        piped
  313.           move.l    winf,cli_StandardInput(a0)
  314.           move.l    winf,pr_CIS(me)
  315.  
  316. piped:        movem.l        savregs,-(sp)
  317.         lea        pr_ReturnAddr(me),a5
  318.         move.l        (a5),-(sp)        ; old pr_ReturnAddr value
  319.         move.l        a5,-(sp)        ; pr_ReturnAddr address
  320.         pea        3000            ; stack size for More
  321.         move.l        sp,(a5)            ; new pr_ReturnAddr
  322.         move.l        mos,d1            ; seglist
  323.         asl.l        #2,d1
  324.         move.l        d1,a3
  325.         move.l        alen,d0
  326.         move.l        aptr,a0
  327.  
  328.         jsr        4(a3)            ; More's entry point!
  329.  
  330.         addq        #4,sp            ; pop stack size
  331.         move.l        (sp)+,a5        ; get pr_ReturnAddr ptr
  332.         move.l        (sp)+,(a5)        ; restore old value
  333.         movem.l        (sp)+,savregs
  334.  
  335.         move.l        d0,d4            ; More's return code
  336.         beq        jesfine
  337.           move.l    #75,d1
  338.           calld        Delay
  339. jesfine:    move.l        winf,d1
  340.         calld        Close
  341.         move.l        (sp)+,a0
  342.         move.l        (sp)+,pr_ConsoleTask(me)
  343.         move.l        (sp)+,cli_StandardInput(a0)
  344.         move.l        (sp)+,pr_COS(me)
  345.         move.l        (sp)+,pr_CIS(me)
  346.         move.l        d4,d0
  347.         rts
  348.  
  349.  
  350. ; ====== this procedure sets alen to be the strlen of aptr.
  351.  
  352. MeasureAptr:    move.l        aptr,a0
  353. nextaptr:    tst.b        (a0)+
  354.         bne.s        nextaptr
  355.         sub.l        aptr,a0
  356.         subq.l        #1,a0
  357.         move.l        a0,alen
  358.         rts
  359.  
  360.  
  361. ; ====== this procedure re-makes the argline with quotes around it.
  362. ; a0 points to buffer space for new line.
  363.  
  364. Mash:        move.l        aptr,a1
  365.         add.l        alen,a1
  366.         subq.l        #1,a1
  367. trim:          cmp.l        aptr,a1
  368.           blt        trimDone
  369.           cmp.b        #' ',(a1)
  370.           bhi        trimDone    ; unsigned char compare
  371.             subq    #1,a1
  372.           bra        trim
  373. trimDone:    sub.l        aptr,a1
  374.         addq.l        #1,a1
  375.         move.l        a1,alen
  376.         beq        nuthin
  377.           move.b    #'"',(a0)+
  378.           move.l    aptr,a1
  379.           move.l    alen,d0
  380. tram:            beq        nuthin
  381.             cmp.b    #'*',(a0)
  382.             beq        starit
  383.             cmp.b    #'"',(a0)
  384.             bne        nostar
  385. starit:              move.b    #'*',(a0)+
  386. nostar:            move.b    (a1)+,(a0)+
  387.             subq    #1,d0
  388.             bra        tram
  389. nuthin:        clr.b        (a0)
  390.         rts
  391.  
  392.  
  393.  
  394. ; ====== this function opens the window and returns the file handle.
  395.  
  396. bufsize        equ        100
  397.  
  398. OpenWin:    lea        -bufsize(sp),sp
  399.         move.l        pr_WindowPtr(me),d4
  400.         move.l        #-1,pr_WindowPtr(me)
  401.         move.l        #MODE_OLDFILE,d2
  402.         lea        ewinname,a0
  403.         move.l        a0,d1
  404.         calld        Open
  405.         move.l        d4,pr_WindowPtr(me)
  406.         tst.l        d0
  407.         beq        default
  408.           move.l    d0,d4        ; read environment var value
  409.           move.l    d4,d1
  410.           move.l    sp,d2        ; result goes on stack
  411.           move.l    #bufsize,d3
  412.           callib    Read
  413.           move.l    d0,-(sp)
  414.           move.l    d4,d1
  415.           callib    Close
  416.           move.l    (sp)+,d0
  417.           ble        default
  418.           cmp.l        #bufsize,d0    ; value too long for buffer?
  419.           bge        default
  420.             move.l    sp,a0
  421.             clr.b    0(a0,d0)    ; make it nul terminated
  422.           bra        openIt
  423. default:    lea        defaultwin,a0
  424. openIt:        move.l        a0,d1
  425.         move.l        #MODE_OLDFILE,d2
  426.         callib        Open
  427.         lea        bufsize(sp),sp
  428.         rts
  429.  
  430.  
  431. ; ====== this function tests whether a resident node has a given name.
  432. ; a0 = (struct theResidents *), a1 = (char *), returns a zero byte if the
  433. ; name of the resident node is the same as the string, ignoring case.
  434.  
  435. CBsame:        move.b        namelength(a0),d2
  436.         lea        name(a0),a0
  437. loupe:          move.b    (a1)+,d0        ; toupper(string[x])
  438.           cmp.b        #'a',d0
  439.           blt        notLow1
  440.             cmp.b    #'z',d0
  441.             bgt        notLow1
  442.               sub.b    #'a'-'A',d0
  443. notLow1:      move.b    (a0)+,d1        ; toupper(name[x])
  444.           cmp.b        #'a',d1
  445.           blt        notLow2
  446.             cmp.b    #'z',d1
  447.             bgt        notLow2
  448.               sub.b    #'a'-'A',d1
  449. notLow2:      cmp.b        d0,d1
  450.           beq        continu
  451.             moveq    #-1,d0            ; names are different
  452.             rts
  453. continu:      subq.b    #1,d2
  454.           beq        dunne
  455.             tst.b    (a1)
  456.             bne        loupe
  457. dunne:        move.b        (a1),d0
  458.         or.b        d2,d0            ; do lengths match?
  459.         rts
  460.  
  461.  
  462. ; ====== this function returns the resident node of More, if it exists.
  463. ; a1 points to name, return value is pointer to struct theResidents.
  464.  
  465. FindResiProg:    move.l        a1,d3
  466.         move.l        dosbase,a0
  467.         move.l        dl_Root(a0),a0
  468.         move.l        rn_Info(a0),d0
  469.         asl.l        #2,d0
  470.         move.l        d0,a0
  471.         move.l        di_NetHand(a0),d0
  472.         asl.l        #2,d0
  473.         move.l        d0,a0        ; the resident segment list
  474. ooop:          move.l    a0,d4
  475.           bsr        CBsame
  476.           move.l    d4,a0
  477.           move.l    d3,a1
  478.           tst.b        d0
  479.           bne        agin
  480.             move.l    a0,d0        ; found it!
  481.             rts
  482. agin:          move.l    next(a0),d0
  483.           asl.l        #2,d0
  484.           move.l    d0,a0
  485.         tst.l        d0
  486.         bne        ooop
  487.         rts                ; didn't find it, return 0
  488.  
  489.